#include "lvgl/lvgl.h"
#include "lv_anim_component.h"
#include <stdio.h>

/**
 * 透明度渐变动画桥接回调函数selector
 * @param var lvgl组件
 * @param v 动画起始值和结束值，设置方式：lv_anim_set_values(&anim, start, end);
 * @return
 */
static void obj_opa_anim_cb(void *var, int32_t v)
{
    lv_obj_set_style_opa(var, v, LV_STATE_DEFAULT);
}
//动画结束回调
void obj_anim_end_cb() {
    printf("anim end.\n");
}

/**
 * 给lvgl组件添加半透明度动画
 * @param obj lvgl组件
 * @param anim_sec 动画时长，单位秒
 * @param enum lv_anim_type 动画枚举类型
 * @return lv_anim_t 动画
 */
static lv_anim_t lvgl_obj_anim(lv_obj_t * obj,
                               const long anim_milli_sec,
                               int32_t start,
                               int32_t end,
                               enum lv_anim_type anim_type) {
    //执行动画
    lv_anim_t anim;
    lv_anim_init(&anim);
    lv_anim_set_var(&anim, obj);
    lv_anim_set_values(&anim, start, end);
    //Q: ✅通过lv_anim_set_values设置动画起始值和结束值，中间 LVGL 自动计算过渡值，然后逐帧调用 exec_cb
    // exec_cb是通过调用lv_anim_set_exec_cb设置的lv_anim_exec_xcb_t exec_cb桥接回调函数参数
    // 用来修改对象组件属性，实现平滑动画效果

    // 动画类型
    switch (anim_type)
    {
    case opa_anim_type: {// 透明度渐变动画
        lv_anim_set_exec_cb(&anim, obj_opa_anim_cb);
        break;
    }

    default:
        break;
    }

    lv_anim_set_time(&anim, anim_milli_sec);
    //动画结束回调
    lv_anim_set_ready_cb(&anim, obj_anim_end_cb);
    lv_anim_start(&anim);
    return anim;
}

/**
 * 给lvgl组件添加半透明度动画
 * @param obj lvgl组件
 * @param anim_sec 动画时长，单位秒
 * @return lv_anim_t 动画
 */
lv_anim_t half_opa_anim(lv_obj_t * obj, const int anim_sec) {
    // 编译报错❌：
    // Undefined symbols for architecture x86_64:
    // "_half_opa_anim", referenced from:
    //     _img_click_event_cb in image_components.c.o
    // ld: symbol(s) not found for architecture x86_64
    // 原因分析✅：image_components.c的img_click_event_cb方法调用的half_opa_anim方法链接错误（linker error），
    // 意思是编译器找不到 half_opa_anim 这个符号（函数或变量）的实现。
    // 解决办法✅：
    // 方案1️⃣：确保找不到的方法所在的.h文件有被调用处的.c文件include进去例如：#include "utils/components/lv_anim_component.h"；
    // 方案2️⃣：方案1️⃣没问题的情况下，可能是half_opa_anim方法内部存在问题，经过分析发现是该方法内调用的lvgl_obj_anim方法没有写在前面
    // 导致调用后接下去才是这个被调用的方法，因此把被调用的lvgl_obj_anim方法写到half_opa_anim方法前面即可；
    return lvgl_obj_anim(obj, anim_sec * 1000, LV_OPA_50, LV_OPA_100, opa_anim_type);
}
